﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


using Kitware.VTK;

namespace HAVTKPack
{
   public  class HydrolicHeadGeometry:Geometry
   {
       #region 构造函数  目前使用的第二个构造函数
       
        public HydrolicHeadGeometry(HydrolicGrid hg)
       {
           this._hg = hg;    
       }

        public HydrolicHeadGeometry(HydrolicGrid hg, List<int[,]> effectiveCellSign)
        {

            this._hg = hg;
            this.EffectiveSign1 = effectiveCellSign;
        }


      
       #endregion

       #region 字段属性

       HydrolicGrid _hg;
       /// <summary>
       /// 不规则网格数据源
       /// </summary>
       public HydrolicGrid Hg
       {
           get { return _hg; }
           set
           {
               //是否改变的判断逻辑有外界（例如参数设置界面）完成，改变时触发该事件  故此处不做是否改变的判断，直接赋值
              
               //bool isChanged = false;
               //isChanged = IsHydrolicGridChanged.IsHyGridChanged(this._hg, value);
               //if (isChanged == true)
               //{
                   _hg = value;
                  this.OnHydrollicGridChanged();
               //}


           }
       }


       List<int[,]> EffectiveSign;
       /// <summary>
       /// 单元的有效性标记数组
       /// </summary>
       public List<int[,]> EffectiveSign1
       {
           get { return EffectiveSign; }
           set
           {

               //是否改变的判断逻辑有外界（例如参数设置界面）完成，改变时触发该事件  故此处不做是否改变的判断，直接赋值

               //bool isChanged = false;
               //isChanged = IsEffectiveScalarSignChanged.IsCellSignChanged(this.EffectiveSign, value);
               //if (isChanged == true)
               //{
                   EffectiveSign = value;
                   this.OnEffectiveSign1Changed();
               //}


           }
       }


       //Vector scaleVector = new Vector(1, 1, 1);



       #endregion



       #region 属性改变

       private void OnHydrollicGridChanged()
       {
           if (this._hg == null)
           {
               return;
           }


           //this.SetPointsArray();

           this.GetPointsAndCellArray();

       }

       private void OnEffectiveSign1Changed()
       {
           if (this.EffectiveSign == null)
           {
               return;
           }

           //this.SetEffectiveCellArray();
           this.GetPointsAndCellArray();

       }

       #endregion



       #region VTK流水线所需要的对象

      vtkUnstructuredGrid unGrid;
      vtkPolyVertex aPolyVertex;



      //vtkTransform _transform;
      //public vtkTransform Transform
      //{
      //    get { return _transform; }
      //    set { _transform = value; }
      //}
      vtkTransformFilter _transFormFilter;


      //vtkFloatArray array;
      //vtkPoints pts;



       #endregion

       public override void Render()
       {
           unGrid = vtkUnstructuredGrid.New();

           //if (this.aPolyVertex==null )
           //{
                aPolyVertex = vtkPolyVertex.New();
           //}
          

           this.GetPointsAndCellArray();

           if (this.GeometryTransform ==null )
           {
               this.GeometryTransform = vtkTransform.New();
           }

           this.GeometryTransform.Identity();
           if (this.ParentNode !=null )
           {
               this.GeometryTransform.Scale(this.ParentNode.Scale.X, this.ParentNode.Scale.Y, this.ParentNode.Scale.Z);
           }
           

           //_transform = vtkTransform.New();

           _transFormFilter = vtkTransformFilter.New();
           _transFormFilter.SetTransform(this.GeometryTransform );
           //_transFormFilter.SetTransform(this._transform);
           _transFormFilter.SetInput(unGrid);


           //this._outPutData = this.unGrid;
           this._outPutData = this._transFormFilter.GetOutput();

        


           //throw new NotImplementedException();
       }

       public override void StopRender()
       {

           if (this._transFormFilter != null)
           {
               this._transFormFilter.Dispose();
           }
           //if (this._transform !=null )
           //{
           //    this._transform.Dispose();
           //}
           if (this.aPolyVertex !=null )
           {
               this.aPolyVertex.Dispose();
           }
           if (this.unGrid !=null )
           {
               this.unGrid.Dispose();
           }
           //if (this.array !=null )
           //{
           //    this.array.Dispose();
           //}
           //if (this.pts !=null )
           //{
           //    this.pts.Dispose();
           //}

           //throw new NotImplementedException();
       }

       #region 公有方法

       //public void UpdateTransformScale(Vector newScaleVector)
       //{
       //    //if (newScaleVector==null )
       //    //{
       //    //    return;
       //    //}

       //    //if (this.scaleVector ==null )
       //    //{
       //    //    this.scaleVector = new Vector(1,1,1);
       //    //}


       //    this.scaleVector.X = newScaleVector.X;
       //    this.scaleVector.Y = newScaleVector.Y;
       //    this.scaleVector.Z = newScaleVector.Z;
    

       //    if (this.GeometryTransform != null)
       //    {
       //        this.GeometryTransform.Identity();
       //        this.GeometryTransform.Scale(this.scaleVector.X, this.scaleVector.Y, this.scaleVector.Z);

       //    }
         
        


       //}


       #endregion





       #region 内部方法

       /// <summary>
       /// 得到点集和单元集  构造网格
       /// </summary>
       private void GetPointsAndCellArray()
       {
           if (this.unGrid == null)
           {
               return;
           }

           //this.SetPointsAndCellArray();


           #region

           int nLayer = this._hg.NLayers;
           int nCol = this._hg.NCols;
           int nRow = this._hg.NRows;
           int nPts = nLayer * nCol * nRow;

           int nPoints = 0;


           #region  构造网格数据集

           //首先确定有效点（对应网格体单元）的个数

           for (int k = 0; k < nLayer; k++)
           {
               for (int i = 0; i < nRow; i++)
               {
                   for (int j = 0; j < nCol; j++)
                   {
                       if (this.EffectiveSign1[k][i, j] != 0)
                       {
                           if (this.EffectiveSign1[k][i, j] < 0)//标记是否有水头
                           {
                               nPoints = nPoints + 1;
                           }

                       }
                   }

               }
           }

           #region vtkPoints

           //if (this.aPolyVertex==null )
           //{
           vtkPolyVertex aPolyVer = vtkPolyVertex.New();
           //}

           aPolyVer.GetPointIds().SetNumberOfIds(nPoints);



           vtkFloatArray array = vtkFloatArray.New();

           array.SetNumberOfComponents(3);

           array.SetNumberOfTuples(nPoints);


           int m = 0;

           Coordinate coord;


           vtkCellArray cellArray = vtkCellArray.New();

           for (int k = 0; k < nLayer; k++)
           {
               for (int i = 0; i < nRow; i++)
               {
                   for (int j = 0; j < nCol; j++)
                   {
                       if (this.EffectiveSign1[k][i, j] != 0)
                       {
                           if (this.EffectiveSign1[k][i, j] < 0)//标记是否有水头
                           {
                               coord = this._hg.Coords[i, j, k];

                               array.SetTuple3(m, coord.X, coord.Y, coord.Z);

                               aPolyVer.GetPointIds().SetId(m, m);

                               //cellArray.insert (m,m );


                               m++;
                           }

                       }
                   }
               }
           }

           vtkPoints pts = vtkPoints.New();
           pts.SetData(array);


           #endregion


           #endregion

           //unGrid.Allocate(1, 1);//主动要求分配内存  很容易破坏内存  安全隐患 。。。。。。。。。怎么解决？？待研究

           unGrid.SetPoints(pts);

           unGrid.InsertNextCell(aPolyVertex.GetCellType(), aPolyVer.GetPointIds());

           //unGrid.SetCells (aPolyVertex.GetCellType(), aPolyVer);


           this.unGrid.Modified ();
           //this.unGrid.Update();


           #endregion

       }




       #region  Point和Cell分别操作


       /// <summary>
       /// 单独改变设置Points
       /// </summary>
       private void SetPointsArray()
       {

           if (this.unGrid == null)
           {
               return;
           }


           int nLayer = this._hg.NLayers;
           int nCol = this._hg.NCols;
           int nRow = this._hg.NRows;
           int nPts = nLayer * nCol * nRow;

           int nPoints = 0;


           #region  构造网格数据集

           #region vtkPoints


           vtkFloatArray array = vtkFloatArray.New();

           array.SetNumberOfComponents(3);

           //array.SetNumberOfTuples(nPoints);


           int m = 0;

           Coordinate coord;

           for (int k = 0; k < nLayer; k++)
           {
               for (int i = 0; i < nRow; i++)
               {
                   for (int j = 0; j < nCol; j++)
                   {
                       if (this.EffectiveSign1[k][i, j] != 0)
                       {
                           if (this.EffectiveSign1[k][i, j] < 0)//标记是否有水头
                           {
                               nPoints = nPoints + 1;

                               coord = this._hg.Coords[i, j, k];

                               array.InsertNextTuple4  (m, coord.X, coord.Y, coord.Z);

                               m++;
                           }

                       }
                   }
               }
           }

           //array.SetNumberOfTuples(nPoints);


           vtkPoints pts = vtkPoints.New();
           pts.SetData(array);


           #endregion


           #endregion

        

           unGrid.SetPoints(pts);


           this.unGrid.Update();




       
       }


       /// <summary>
       /// 单独改变设置Cell
       /// </summary>
       private void SetEffectiveCellArray()
       {
           if (this.unGrid == null)
           {
               return;
           }



           int nLayer = this._hg.NLayers;
           int nCol = this._hg.NCols;
           int nRow = this._hg.NRows;
           int nPts = nLayer * nCol * nRow;

           int nPoints = 0;


           #region  构造网格数据集


           #region vtkPoints

         
           vtkPolyVertex aPolyVer = vtkPolyVertex.New();
     


           int m = 0;

    

           vtkCellArray cellArray = vtkCellArray.New();

           for (int k = 0; k < nLayer; k++)
           {
               for (int i = 0; i < nRow; i++)
               {
                   for (int j = 0; j < nCol; j++)
                   {
                       if (this.EffectiveSign1[k][i, j] != 0)
                       {
                           if (this.EffectiveSign1[k][i, j] < 0)//标记是否有水头
                           {

                               nPoints = nPoints + 1;

                               aPolyVer.GetPointIds().InsertId(m,m );

                               //aPolyVer.GetPointIds().SetId(m, m);


                               m++;
                           }

                       }
                   }
               }
           }

           //aPolyVer.GetPointIds().SetNumberOfIds(nPoints);


           #endregion


           #endregion

       

           unGrid.InsertNextCell(aPolyVertex.GetCellType(), aPolyVer.GetPointIds());

         

           this.unGrid.Update();




       
       
       
       }


       /// <summary>
       /// 同时改变 Points 和 Cell  用于Render调用
       /// </summary>
       private void SetPointsAndCellArray()
       {

           if (this.unGrid == null)
           {
               return;
           }


           int nLayer = this._hg.NLayers;
           int nCol = this._hg.NCols;
           int nRow = this._hg.NRows;
           int nPts = nLayer * nCol * nRow;

           int nPoints = 0;


           #region  构造网格数据集

   

           #region vtkPoints

           
           vtkPolyVertex aPolyVer = vtkPolyVertex.New();
   

           vtkFloatArray array = vtkFloatArray.New();

           array.SetNumberOfComponents(3);

     
           int m = 0;

           Coordinate coord;


           vtkCellArray cellArray = vtkCellArray.New();

           for (int k = 0; k < nLayer; k++)
           {
               for (int i = 0; i < nRow; i++)
               {
                   for (int j = 0; j < nCol; j++)
                   {
                       if (this.EffectiveSign1[k][i, j] != 0)
                       {
                           if (this.EffectiveSign1[k][i, j] < 0)//标记是否有水头
                           {

                               nPoints = nPoints + 1;

                               coord = this._hg.Coords[i, j, k];

                               array.InsertNextTuple4 (m, coord.X, coord.Y, coord.Z);

                               aPolyVer.GetPointIds().InsertId (m, m);

                               m++;
                           }

                       }
                   }
               }
           }
           //aPolyVer.GetPointIds().SetNumberOfIds(nPoints);
           //array.SetNumberOfTuples(nPoints);

           vtkPoints pts = vtkPoints.New();

           pts.SetData(array);


           #endregion


           #endregion

 
           unGrid.SetPoints(pts);

           unGrid.InsertNextCell(aPolyVertex.GetCellType(), aPolyVer.GetPointIds());


           this.unGrid.Update();



       }



       #endregion





       #endregion




   }


}
